#include <REGX52.H>
#include "DS1302.h"

sbit DS1302_SCLK = P3^6;
sbit DS1302_IO = P3^4;
sbit DS1302_CE = P3^5;

/** @bref DS1302初始化
  * @param 无
  * @retval 无
  */
void DS1302_init()
{
	DS1302_CE = 0;
	DS1302_SCLK = 0;
}

/** @bref 向DS1302写入一个字节
  * @param command 写入的命令地址
  * @param byte 写入一个字节数据
  * @retval 无
  */
void DS1302_writeByte(unsigned char command, byte)
{
	unsigned char i = 0;
	DS1302_CE = 1;
	
	for(i = 0; i < 8; i++)
	{
		// 写入第i位（其他位清0，第i位保持原样）
		DS1302_IO = command & (0x01 << i);
		DS1302_SCLK = 1;
		DS1302_SCLK = 0;
	}
	for(i = 0; i < 8; i++)
	{
		// 写入第i位（其他位清0，第i位保持原样）
		DS1302_IO = byte & (0x01 << i);
		DS1302_SCLK = 1;
		DS1302_SCLK = 0;
	}
	DS1302_CE = 0;
}

/** @bref 从DS1302中读取一个字节
  * @param command 读取的命令地址
  * @retval 读取到的字节
  */
unsigned char DS1302_readByte(unsigned char command)
{
	unsigned char byte = 0x00;
	unsigned char i = 0;
	DS1302_CE = 1;
	//将读指令转换为对应的写指令（最低位置1，其他位不变）
	command |= 0x01;

	for(i = 0; i < 8; i++)
	{
		// 读入第i位（其他位清0，第i位保持原样）
		DS1302_IO = command & (0x01 << i);
		DS1302_SCLK = 0;
		DS1302_SCLK = 1;
	}
	for(i = 0; i < 8; i++)
	{
		DS1302_SCLK = 1;
		DS1302_SCLK = 0;
		// 若读取数据为1
		if(DS1302_IO)
		{
			// 则把数据的第i位置1
			byte |= (0x01 << i);
		}
	}
	DS1302_CE = 0;
	DS1302_IO = 0;	//读取后将IO设置为0，否则读出的数据会出错
	
	return byte;
}

/** @bref 两位十进制转BCD码
  * @param 要转的十进制数
  * @retval 转换后的BCD码
  */
unsigned char getBCDFromDec(unsigned char dec)
{
	return dec/10 *16 + dec%10;
}

/** @bref 两位BCD码转十进制
  * @param 要转的BCD码
  * @retval 转换后的十进制数
  */
unsigned char getDecFromBCD(unsigned char bcd)
{
	return bcd/16 *10 + bcd%16;
}

/** @bref 设置时间信息
  * @param 向DS1302中设置的时间数组
  * @retval 无
  */
void DS1302_setTime(unsigned char DS1302_timeArr[])
{
	// 先打开写保护
	DS1302_writeByte(DS1302_RTC_WRITE_WP, 0x00);
	
	// 都需要十进制转BCD码后写入
	DS1302_writeByte(DS1302_RTC_WRITE_YEAR, getBCDFromDec(DS1302_timeArr[0]));
	DS1302_writeByte(DS1302_RTC_WRITE_MONTH, getBCDFromDec(DS1302_timeArr[1]));
	DS1302_writeByte(DS1302_RTC_WRITE_DATE, getBCDFromDec(DS1302_timeArr[2]));
	DS1302_writeByte(DS1302_RTC_WRITE_HOUR, getBCDFromDec(DS1302_timeArr[3]));
	DS1302_writeByte(DS1302_RTC_WRITE_MINUTE, getBCDFromDec(DS1302_timeArr[4]));
	DS1302_writeByte(DS1302_RTC_WRITE_SECOND, getBCDFromDec(DS1302_timeArr[5]));
	DS1302_writeByte(DS1302_RTC_WRITE_DAY, getBCDFromDec(DS1302_timeArr[6]));
	
  DS1302_writeByte(DS1302_RTC_WRITE_WP, 0x01);
}

/** @bref 设置时间信息
  * @param 向DS1302中设置的时间数组
  * @retval 无
  */
void DS1302_getTime(unsigned char DS1302_timeArr[])
{
	// 都需要把BCD码转十进制后写入
	DS1302_timeArr[0] = getDecFromBCD(DS1302_readByte(DS1302_RTC_WRITE_YEAR));
	DS1302_timeArr[1] = getDecFromBCD(DS1302_readByte(DS1302_RTC_WRITE_MONTH));
	DS1302_timeArr[2] = getDecFromBCD(DS1302_readByte(DS1302_RTC_WRITE_DATE));
	DS1302_timeArr[3] = getDecFromBCD(DS1302_readByte(DS1302_RTC_WRITE_HOUR));
	DS1302_timeArr[4] = getDecFromBCD(DS1302_readByte(DS1302_RTC_WRITE_MINUTE));
	DS1302_timeArr[5] = getDecFromBCD(DS1302_readByte(DS1302_RTC_WRITE_SECOND));
	DS1302_timeArr[6] = getDecFromBCD(DS1302_readByte(DS1302_RTC_WRITE_DAY));
}
